Python의 내장 모듈 itertools는 다양한 반복자를 제공한다.
이를 이용하면 반복문을 사용하지 않고도 풀 수 있는 문제들이 많다.
특히 'N과 M' 시리즈의 문제는 수열을 다양한 방식으로 출력해야 하는 문제로 itertools를 사용하면 매우 간단하게 풀 수 있다.
이번 글에서는 백준 'N과 M' 시리즈의 문제를 Python 내장 모듈인 itertools로 풀어보자.
accumulate(iterable[, func, *, initial=None]): iterable의 누적값 배열을 생성한다. func가 주어지지 않으면 operator.add를 사용한다. initial이 주어지면 iterable의 첫번째 원소 앞에 initial을 추가한다. 최종 누적값만이 필요한 경우 iterable.reduce를 사용하는 것이 더 빠르다.
from itertools import takewhileprint(list(takewhile(lambda x: x < 5, [1, 4, 6, 4, 1])))# [1, 4]
tee(iterable, n=2): iterable을 n개의 복사본으로 분리한다. iterable을 여러 번 사용해야 할 때 유용하다.
from itertools import teea, b, c = tee('ABC', 3)print(list(a))# ['A', 'B', 'C']print(list(b))# ['A', 'B', 'C']print(list(c))# ['A', 'B', 'C']
zip_longest(*iterables, fillvalue=None): iterables의 요소를 튜플로 묶어서 생성한다. zip과 유사하지만, zip은 최단 iterable이 끝날 때까지만 생성하는 데에 반해 zip_longest는 최장 iterable이 끝날 때까지 생성한다. 최장 iterable보다 짧은 iterable의 요소는 fillvalue로 채운다.
from itertools import zip_longestprint(list(zip_longest('ABCD', 'xy', fillvalue='-')))# [('A', 'x'), ('B', 'y'), ('C', '-'), ('D', '-')]# zip 이었다면 [('A', 'x'), ('B', 'y')]
1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열을 사전순으로 출력해야한다.
중복 없는 수열이므로 순열 즉, itertools.permutations를 사용한다.
from itertools import permutationsN, M = map(int, input().split())nums = [str(i) for i in range(1, N + 1)]# join을 사용하기 위해 미리 문자열로 변환combs = permutations(nums, M)print('\n'.join(' '.join(comb) for comb in combs))
1부터 N까지 자연수 중에서 중복 없이 M개를 고른 오름차순의 수열을 사전순으로 출력해야한다.
중복 없는 오름차순 수열이므로 조합 즉, itertools.combinations를 사용한다.
from itertools import combinationsN, M = map(int, input().split())nums = [str(i) for i in range(1, N + 1)]combs = combinations(nums, M)print('\n'.join(' '.join(comb) for comb in combs))
1부터 N까지 자연수 중에서 M개를 고른 수열을 사전순으로 출력해야한다.
중복이 허용되므로 itertools.product를 사용한다.
from itertools import productN, M = map(int, input().split())nums = [str(i) for i in range(1, N + 1)]combs = product(nums, repeat=M)print('\n'.join(' '.join(comb) for comb in combs))
1부터 N까지 자연수 중에서 M개를 고른 비내림차순 수열을 사전순으로 출력해야한다.
비내림차순 수열이므로 중복을 허용하는 조합 즉, itertools.combinations_with_replacement를 사용한다.
from itertools import combinations_with_replacementN, M = map(int, input().split())nums = [str(i) for i in range(1, N + 1)]combs = combinations_with_replacement(nums, M)print('\n'.join(' '.join(comb) for comb in combs))
주어진 중복되지 않는 N개의 수 중에서 중복 없이 M개를 고른 오름차순 수열을 사전순으로 출력해야한다.
2번과 비슷하지만 주어진 수열이 있으므로 이를 정렬해야 한다.
from itertools import combinationsN, M = map(int, input().split())nums = sorted(input().split(), key=int)combs = combinations(nums, M)print('\n'.join(' '.join(comb) for comb in combs))
주어진 중복되지 않는 N개의 수 중에서 M개를 고른 오름차순 수열을 사전순으로 출력해야한다.
3번과 비슷하지만 주어진 수열이 있으므로 이를 정렬해야 한다.
from itertools import productN, M = map(int, input().split())nums = sorted(input().split(), key=int)combs = product(nums, repeat=M)print('\n'.join(' '.join(comb) for comb in combs))
주어진 중복되지 않는 N개의 수 중에서 M개를 고른 비내림차순 수열을 사전순으로 출력해야한다.
4번과 비슷하지만 주어진 수열이 있으므로 이를 정렬해야 한다.
from itertools import combinations_with_replacementN, M = map(int, input().split())nums = sorted(input().split(), key=int)combs = combinations_with_replacement(nums, M)print('\n'.join(' '.join(comb) for comb in combs))
주어진 N개의 수 중에서 중복 없이 M개를 고른 수열을 사전순으로 출력해야한다.
5번과 비슷하지만 중복된 수가 주어질 수 있으므로 수열을 정렬해야 한다.
from itertools import permutationsN, M = map(int, input().split())nums = map(int, input().split())combs = sorted(set(permutations(nums, M)))print('\n'.join(' '.join(map(str, comb)) for comb in combs))
주어진 N개의 수 중에서 중복 없이 M개를 고른 비내림차순 수열을 사전순으로 출력해야한다.
8번과 비슷하지만 중복된 수가 주어질 수 있으므로 주어진 수와 수열을 정렬해야 한다.
from itertools import combinationsN, M = map(int, input().split())nums = sorted(map(int, input().split()))combs = sorted(set(combinations(nums, M)))print('\n'.join(' '.join(map(str, comb)) for comb in combs))